package cz.spock.core.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import cz.spock.core.service.RegistrationService;
import cz.spock.exception.DatabaseException;
import cz.spock.exception.InvalidDataException;
import cz.spock.exception.InvalidInputException;

/**
 * handles registration related urls
 * 
 * @author miso
 *
 */
@Controller
public class RegistrationController extends BaseController {
    
    @Autowired
    private RegistrationService regService;
    
    /**
     * URL: /ajax/registration
     * Method: POST
     * 
     * Ajax service for registration request
     * 
     * Params:
     * - email - string, not null, must be valid email address
     * - inviter - string (key of account as string)
     * - type - string, describes type of account, default is "user"
     * - validuntil - integer, validity of link in hours (0 = default value 1 day)
     * 
     * Error messages:
     * - 400 parameter not found
     * - 410 invalid data
     * - 500 internal error
     * - 420 data problem - email is already used
     * 
     * Status: not tested
     * 
     * @param request
     * @param response
     */
    @RequestMapping(value = "/ajax/registration", method = RequestMethod.POST)
    public void createRegistration(HttpServletRequest request, HttpServletResponse response) {
        // email
        String email = this.readParamAsString(request, "email");
        String invitedBy = this.readParamAsString(request, "inviter");
        String accType = this.readParamAsString(request, "type");
        int validUntil;
        try {
            validUntil = this.readParamAsInt(request, "validuntil");
        } catch(Exception e) {
            sendJson(response, regService.errorToJson("Parameter validuntil must be number.", 410));
            return;            
        }
        // calls service
        try {
            regService.createRegistration(email, invitedBy, accType, true, validUntil);
        } catch(InvalidInputException e) {
            sendJson(response, regService.errorToJson(e.getMessage(), e.getErrorCode()));
            return;
        } catch(InvalidDataException e) {
            sendJson(response, regService.errorToJson(e.getMessage(), e.getErrorCode()));
            return;
        } catch(DatabaseException e) {
            sendJson(response, regService.errorToJson(e.getMessage(), e.getErrorCode()));
            return;
        } catch(Exception e) {
            log.severe("Exception in RegistrationController method createAccount: " + e.getMessage());
            sendJson(response, regService.errorToJson("Internal error.", 500));
            return;            
        }
        // success message
        log.finest("registration request done");
        sendJson(response, regService.responseToJson(null));
    }
    
    /**
     * URL: /ajax/registration/request
     * Method: POST
     * 
     * Ajax service for registration request, receives http request(email) and
     * sends json data
     * 
     * Params:
     * - email - string, not null, must be valid email address
     * 
     * Error messages:
     * - 400 parameter not found
     * - 410 invalid data
     * - 500 internal error
     * - 420 data problem - email is already used
     * 
     * Status: not tested, deprecated
     * 
     * @param request
     * @param response
     */
    @Deprecated // createRegistration should be used instead
    @RequestMapping(value = "/ajax/registration/request", method = RequestMethod.POST)
    public void requestRegistration(HttpServletRequest request, HttpServletResponse response) {
        String email = this.readParamAsString(request, "email");
        
        // registration logic
        try {
            regService.createRegistration(email, null, null, true, 0);
        } catch(InvalidInputException e) {
            sendJson(response, regService.errorToJson(e.getMessage(), e.getErrorCode()));
            return;
        } catch(InvalidDataException e) {
            sendJson(response, regService.errorToJson(e.getMessage(), e.getErrorCode()));
            return;
        } catch(DatabaseException e) {
            sendJson(response, regService.errorToJson(e.getMessage(), e.getErrorCode()));
            return;
        } catch(Exception e) {
            log.severe("Exception in RegistrationController method createAccount: " + e.getMessage());
            sendJson(response, regService.errorToJson("Internal error.", 500));
            return;            
        }
        // success message
        log.finest("registration request done");
        String json = regService.responseToJson(null);
        sendJson(response, json);
    }
    
    /**
     * URL: /ajax/registration/{hash}
     * Method: GET
     * 
     * Ajax service link verification. Can be used before displaying registration form.     
     * 
     * Params:
     * 
     * Error messages:
     * 
     * Status: not implemented
     * 
     * @param link
     * @param request
     * @param response
     * @return
     */
    // TODO
    @RequestMapping(value = "/ajax/registration/{link}", method = RequestMethod.GET)
    public String registrationVerify(@PathVariable String link, HttpServletRequest request, HttpServletResponse response) {
        boolean valid = regService.verifyRegistrationLink(link);
        if (!valid) {
            log.fine("hash invalid");
            return "errorpage";
        }
        log.fine("hash valid");
        return "registration";
    }
    
    
    /**
     * verifies registration link (not supposed to be used as ajax service)
     * 
     * @param link
     * @param request
     * @param response
     * @return jsp page for registration
     */
    @RequestMapping(value = "/registration/{link}", method = RequestMethod.GET)
    public String registrationLink(@PathVariable String link, HttpServletRequest request, HttpServletResponse response) {
        log.fine("registration hash verification");
        boolean valid = regService.verifyRegistrationLink(link);
        if (!valid) {
            log.fine("hash invalid");
            return "errorpage";
        }
        log.fine("hash valid");
        return "registration";
    }
    
}
